package mapEditor.interactor;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;

import mapEditor.map.MapCanvas;
import mapEditor.utils.MapLocation;


public class ZoomInteractor extends MapInteractorAdapter
{ public String getMouseModeMnemonic() { return("Zoom"); }
  private static final BasicStroke markerStroke
          =new BasicStroke(1,BasicStroke.CAP_SQUARE,BasicStroke.JOIN_MITER,10,new float[]{4,4},0);
  private boolean zooming; // true while zooming


  // ******************************************************************
  // *** CONSTRUCTOR: ZoomInteractor
  // ******************************************************************
  public ZoomInteractor(MapCanvas mapCanvas)
  { super(mapCanvas,ZOOM); }

  /**
  * Tells whether the interactor has finished.
  */
  public boolean endInteraction() { return(!zooming); }

  // ******************************************************************
  // *** METHOD: paintMouseEffect
  // ******************************************************************
  public void paintMouseEffect(Graphics2D g)
  { if(!!zooming)
    { g.setXORMode(Color.white);
      g.setColor(Color.black);
      g.setStroke(markerStroke);
      g.draw(getShape());
    }        
  }

  protected Shape getShape()
  { double x0=mouseStart.getX();
    double y0=mouseStart.getY();
    double x1=mouseCurrent.getX();
    double y1=mouseCurrent.getY();
    double x=Math.min(x0,x1);
    double y=Math.min(y0,y1);
    double width=Math.abs(x1-x0);
    double height=Math.abs(y1-y0);
    Rectangle2D shape=new Rectangle2D.Double(x,y,width,height);
    return(shape);	  
  }

  // ******************************************************************
  // *** METHOD: mouseDragged
  // ******************************************************************
  // Invoked when a mouse button is pressed and then dragged.
  protected void mouseDragged() { mapCanvas.repaint(); }

  // ******************************************************************
  // *** METHOD: mouseMoved
  // ******************************************************************
  // Invoked when the mouse has been moved (with no buttons down).
  protected void mouseMoved() {}

  // ******************************************************************
  // *** METHOD: mousePressed
  // ******************************************************************
  // Invoked when a mouse button has been pressed.
  protected void mouseLeftPressed(MapLocation p)
  {	if(!zooming)
    { zooming=true;
      mouseStart=p;
    }
  }
  protected void mouseRightPressed(MapLocation p) {}


  // ******************************************************************
  // *** METHOD: mouseReleased
  // ******************************************************************
  // Invoked when a mouse button has been released.
  protected void mouseLeftReleased(MapLocation p)
  { zooming=false;
    int x0=(int)mouseStart.getX();
    int y0=(int)mouseStart.getY();
    int x1=(int)p.getX();
    int y1=(int)p.getY();
	int dx=x1-x0;
    int dy=y1-y0;

    float scale=1.2f;
    if(dx!=0 && dy!=0)
    { if(dx<0) { dx = -dx; x0=x1; }
      if(dy<0) { dy = -dy; y0=y1; }
      Dimension size=mapCanvas.getSize();
      // Zoom factor
      float scaleX = size.width / (float)dx;
      float scaleY = size.height / (float)dy;
      scale = (scaleX < scaleY) ? scaleX : scaleY;
    }
    // TODO: TEST
    mapCanvas.getDOMTree().zoom(true);
//    mapCanvas.requestResize();
    scale=(float)mapCanvas.getDOMTree().getZoomFactor();
      // Zoom translate
      AffineTransform at = new AffineTransform();
      at.scale(scale, scale);
//      at.translate(-x0, -y0);

      at.concatenate(mapCanvas.getRenderingTransform());
      mapCanvas.setRenderingTransform(at);
      mapCanvas.requestResize();    
  }

  protected void mouseRightReleased(MapLocation p)
  { float scale=0.5f;
    // TODO: TEST
    mapCanvas.getDOMTree().zoom(false);
//    mapCanvas.requestResize();
    scale=1/(float)mapCanvas.getDOMTree().getZoomFactor();
    
    // Zoom OUT translate
    AffineTransform at = new AffineTransform();
    at.scale(scale, scale);
//    at.translate(-x0, -y0);
    at.concatenate(mapCanvas.getRenderingTransform());
    mapCanvas.setRenderingTransform(at);
    mapCanvas.requestResize();
  }


}
